'''
给定一个字符串 s ，请你找出其中不含有重复字符的、最长连续子字符串 的长度。

示例 1：
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子字符串是 "abc"，所以其长度为 3。

示例 2：
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子字符串是 "b"，所以其长度为 1。

示例 3：
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke"，所以其长度为 3。
     请注意，你的答案必须是 子串 的长度，"pwke" 是一个子序列，不是子串。

示例 4：
输入: s = ""
输出: 0

提示： 0 <= s.length <= 5 * 10^4     s 由英文字母、数字、符号和空格组成
'''



'''
代码解释
char_map 字典：用于存储每个字符最后一次出现的索引位置。
left 指针：表示当前无重复子串的左边界。
right 指针：遍历字符串，作为当前无重复子串的右边界。
当遍历到字符 s[right] 时，如果该字符在 char_map 中且其最后出现的索引大于等于 left，说明该字符在当前窗口内重复，此时需要将 left 移动到该字符上一次出现位置的下一个位置，
以保证窗口内无重复字符。
每次遍历都会更新 char_map 中当前字符的索引，并计算当前窗口的长度（right - left + 1），同时更新 max_length 为最大的窗口长度。
这种方法的时间复杂度是 O(n)，其中 n 是字符串的长度，因为每个字符最多被访问两次（左指针和右指针各一次）；空间复杂度是 O(k)，其中 k 是字符集的大小，用于存储 char_map。
'''

def lengthOfLongestSubstring(s):
    # 用于记录字符最后出现的索引
    char_map = {}
    # 左指针，窗口的左边界
    left = 0
    # 最长无重复子串的长度
    max_length = 0
    for right in range(len(s)):
        # 如果当前字符在窗口中出现过
        if s[right] in char_map:
            # 移动左指针到重复字符的下一个位置（取较大值，防止左指针回退）
            left = max(left, char_map[s[right]] + 1)
        # 更新当前字符最后出现的索引
        char_map[s[right]] = right
        # 更新最长长度
        max_length = max(max_length, right - left + 1)
    return max_length
# 测试示例
print(lengthOfLongestSubstring("abcabcbb"))  # 输出 3
print(lengthOfLongestSubstring("bbbbb"))     # 输出 1
print(lengthOfLongestSubstring("pwwkew"))    # 输出 3
print(lengthOfLongestSubstring(""))          # 输出 0